#ifndef LSM_H
#define LSM_H
/***
    LSM class
*/
#include <nemo.hpp>
#include <math.h>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <stdlib.h>

#include "NeuronType.hh"

using std::vector;
using namespace nemo;

class LSM {

private:
  // Nemo components
  Network _net;
  Configuration _conf;
  Simulation *_sim;
  
  // LSM Params
  int _X, _Y, _Z;

  float lambda;

  std::set<std::string> nemoTypes;
  
  // TODO - possibly set this up as non-* w/ copy cstr
  float max_fraction;
  std::map<float, NeuronType*> neuron_allocation_map;
 
 // 
  struct pos {
    int x;
    int y;
    int z;
  };

  bool initialized;

  NeuronType* neuronTypeToAdd(void);
 
public:
  LSM(int x, int y, int z);
  ~LSM(void);

  void addNeuronType(NeuronType* nt, float fraction);

  // Initialize network 
  void init(void);

  const vector<unsigned> step(void);

public:
  // inline convenience functions
  int coord2indx(int x, int y, int z) {
    return (_X * _Y * z) + (_X * y ) + x;
  }

  int pos2indx(pos p) {
    return (_X * _Y * p.z) + (_X * p.y ) + p.x;
  }

  pos indx2pos(int idx) {
    
    pos coords;

    coords.z = floor( idx / (_Y * _X) );

    int sheet = (idx - (_Y * _X * coords.z) );
    coords.y = floor( sheet / _X );
    coords.x = sheet % _X;

    return coords;
  }
    
};
#endif
